home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / docs / perl / perl20.doc < prev   
Text File  |  2000-06-25  |  20KB  |  793 lines

  1.  
  2.  
  3.  
  4.  
  5.                    おきらくPerlプログラミング入門
  6.                       ~~めざせ Perl マスター~~
  7.  
  8.                                 広井  誠
  9.  
  10.                                  最終回
  11.  
  12.  
  13.  
  14.  
  15. ○タイ(tie)
  16.  
  17.   この講座も最終回となりましたが、最後は変数とクラスを結び付ける働きをす
  18.  
  19. るタイ(tie) について説明します。タイは、リファレンスやオブジェクト指向と
  20.  
  21. ともに、Perl 5 から追加された機能です。タイは、変数とユーザー定義のクラ
  22.  
  23. スを結び付ける働きをし、変数の読み出しや書き込みのタイミングで、特定のメ
  24.  
  25. ソッドを呼び出すことができます。変数には、スカラー、配列、ハッシュ、ファ
  26.  
  27. イルハンドルを指定することができます。タイを使うことで、特定の変数を監視
  28.  
  29. するといったデバッグツールの作成や、データベースとハッシュを結び付けるこ
  30.  
  31. とで、データベースへのアクセスを簡単に行うことができます。
  32.  
  33.  
  34. ○スカラーとタイ
  35.  
  36.   まずは、スカラーから説明しましょう。変数とクラスを結び付けるには、関数 
  37.  
  38. tie を使います。
  39.  
  40.  
  41.     tie variable, classname, list;  
  42.  
  43.  
  44. 関数 tie は変数 variable をクラス classname に結び付けます。このように結
  45.  
  46. び付けられた変数をタイ変数といいます。tie は、クラス classname に定義さ
  47.  
  48. れている特別なメソッドを呼び出します。これは変数の種類によって異なります。
  49.  
  50.  
  51.         変数の種類       |呼び出されるメソッド
  52.         -----------------+--------------------
  53.         スカラー         |  TIESCALAR
  54.         配列             |  TIEARRAY
  55.         ハッシュ         |  TIEHASH
  56.         ファイルハンドル |  TIEHANDLE  
  57.  
  58.  
  59. スカラーの場合は、TIESCALAR が呼び出されます。この時、tie に与えられた
  60.  
  61. list が引数として渡されます。つまり、TIESCALAR は次のように呼び出されま
  62.  
  63. す。
  64.  
  65.  
  66.         classname->TIESCALAR( list );
  67.  
  68.  
  69. tie から呼び出されるこれらのメソッドは、オブジェクトを返さなければいけま
  70.  
  71. せん。このオブジェクトと変数 [*1] が結び付けられます。
  72.  
  73.   スカラーがタイ変数になると、変数にアクセスするたびに、次のメソッドが呼
  74.  
  75. び出されます。
  76.  
  77.  
  78.        アクション   | 呼び出されるメソッド
  79.        -------------+--------------------------
  80.        読み出し     | $obj->FETCH();
  81.        書き込み     | $obj->STORE( $new_value );
  82.        廃棄         | $obj->DESTROY();
  83.  
  84.  
  85. 廃棄には、関数 untie によってタイを解除する、関数 undef によって変数を未
  86.  
  87. 定義にする、局所変数が有効範囲から出る(スコープの終了)ことの3通りがあ
  88.  
  89. ります。変数がタイ変数となると、変数としての機能が失われる、つまり、値の
  90.  
  91. 読み書きができなくなることに注意してください。値を保存したい場合は、オブ
  92.  
  93. ジェクトにインスタンス変数を用意して、メソッド FETCH で変数の値を読み出
  94.  
  95. す、STORE で変数へ値を書き込む処理が必要になります。
  96.  
  97.  
  98.   それでは簡単な実行例として、スカラー変数のアクセスを監視するプログラム
  99.  
  100. を作ってみましょう。最初にクラス MonScalar を定義します。
  101.  
  102.  
  103.   package MonScalar;
  104.  
  105.   sub TIESCALAR {
  106.     my ($pkg, $name, $value) = @_;
  107.     my $obj = { name => $name, value => $value };
  108.     bless $obj, $pkg;
  109.     $obj;
  110.   }
  111.  
  112.   sub FETCH {
  113.     my $obj = shift;
  114.     print 'Read : $', $obj->{'name'}, " -> $obj->{'value'}\n";
  115.     $obj->{'value'};
  116.   }
  117.  
  118.   sub STORE {
  119.     my ($obj, $new_value) = @_;
  120.     print 'Write : $', $obj->{'name'}," <- $new_value\n";
  121.     $obj->{'value'} = $new_value;
  122.   }
  123.  
  124.   sub DESTROY {
  125.     print "DESTORY\n";
  126.   }
  127.  
  128.  
  129.   TIESCALAR には引数として、変数名とその値を渡します。オブジェクトとして
  130.  
  131. 無名のハッシュを生成して、変数名は name に、値は value にセットします。
  132.  
  133. 後はオブジェクトをブレスして返すだけです。
  134.  
  135.   FETCH は簡単です。オブジェクトから名前と値を取り出して print で出力し
  136.  
  137. ます。FETCH の返り値がその変数の値として扱われるので、値をそのまま返しま
  138.  
  139. す。STORE も簡単ですね。書き込まれる値が引数として渡されるので、それをオ
  140.  
  141. ブジェクトの value に保存するだけです。
  142.  
  143.   それでは実行してみましょう。
  144.  
  145.  
  146.   package main;
  147.  
  148.   $x = 10;
  149.   tie $x, 'MonScalar', 'x', $x;
  150.   $y = $x;
  151.   print "y = $y\n";
  152.   $x = 100;
  153.   $z = $x;
  154.   print "z = $z\n";
  155.   untie $x;
  156.   print "x = $x\n";
  157.  
  158.  
  159.   実行結果
  160.  
  161.   Read : $x -> 10
  162.   y = 10
  163.   Write : $x <- 100
  164.   Read : $x -> 100
  165.   z = 100
  166.   DESTORY
  167.   x = 100
  168.  
  169.  
  170.   最初に tie を使って変数 $x とクラス MonScalar を結び付けます。tie の返
  171.  
  172. り値は、TIESCALAR で返すオブジェクトです。このオブジェクトを使って特別な
  173.  
  174. メソッド FETCH や STORE を呼び出すことができます。また、tied 関数を使っ
  175.  
  176. て、変数に結び付けられたオブジェクトを取り出すこともできます。たとえば、
  177.  
  178. $x = 100; は (tied $x)->STORE( 100 ); と同じ動作になります。
  179.  
  180.   この後 $x にアクセスするたびに、MonScalar のメソッド FETCH と STORE が
  181.  
  182. 呼び出されます。untie を実行すると、メソッド DESTORY が呼び出されます。
  183.  
  184. ここで変数 $x の値に注意してください。参考文献によると、「タイされた変数
  185.  
  186. について untie 関数を呼び出すと、変数の値は元に復元される」とのことです。
  187.  
  188. ところが、$x は書き換えた値 100 になっています。どうやらスカラーの場合は、
  189.  
  190. 元の値には復元されないようです。配列やハッシュでは、元の値に復元されます。
  191.  
  192. Windows で動作する ActivePerl 5.005 でも、スカラーの値は復元されませんが、
  193.  
  194. 配列とハッシュの値は元に戻ります。スカラーでも元の値に復元される処理系が
  195.  
  196. あるかもしれません。そこで、untie されると変数の値は復元されることを前提
  197.  
  198. に話を進めます。
  199.  
  200.  
  201.   [*1]  正確に説明すると、変数に格納されているデータ(スカラー、配列、ハッ
  202.         シュやファイルハンドル)とオブジェクトが結び付けられます。変数自
  203.         身と結びつくわけではないことに注意してください。
  204.  
  205.  
  206. ○変数の値を更新する
  207.  
  208.   監視を止めると変数の値が元に戻るようでは、監視の役目を果たしているとは
  209.  
  210. いえません。かえって、ユーザーを混乱させるだけです。変数の値は、オブジェ
  211.  
  212. クトに格納されているので、監視を止める時に値を更新することにしましょう。
  213.  
  214. この処理をメソッド unmonitor で行うことにします。
  215.  
  216.   [注意]  X68k 版 Perl 5 では関数 tied を呼び出すことができないので(未
  217.           実装?)、これ以降のプログラムは ActivePerl 5.005 で動作チェッ
  218.           クを行いました。
  219.  
  220.  
  221.   # 監視を止める
  222.   sub unmonitor {
  223.     my ($pkg, $rvar) = @_;
  224.     my $obj = tied $$rvar;
  225.     my $last_value = $obj->{'value'};
  226.     untie $$rvar;
  227.     $$rvar = $last_value;
  228.   }
  229.  
  230.  
  231. このメソッドは MonScalar->unmonitor( \$x ); と呼び出します。リファレンス
  232.  
  233. を使って変数を渡すことに注意してください。関数 tied でオブジェクトを取り
  234.  
  235. 出し、そこに格納されている値を $last_value にセットします。その後、untie
  236.  
  237. でタイを解除してから、変数の値を $last_value に更新します。
  238.  
  239.  
  240.   これで正常に動作するように思いますが、実は不具合があるのです。-w オプ
  241.  
  242. ションを付けて perl を実行すると、次のメッセージが表示されます。
  243.  
  244.  
  245.   untie attempted while 1 inner references still exist ...
  246.  
  247.     
  248. これは局所変数 $obj がタイ変数のオブジェクトを参照しているため、オブジェ
  249.  
  250. クトのリファレンスカウントが 0 にならず、untie がオブジェクトを廃棄でき
  251.  
  252. ないことを表しています。この問題は、局所変数 $obj の有効範囲を限定するこ
  253.  
  254. とで解決することができます。
  255.  
  256.  
  257.   # 監視を止める(修正版)
  258.   sub unmonitor {
  259.     my ($pkg, $rvar) = @_;
  260.     my $last_value;
  261.     {
  262.       my $obj = tied $$rvar;
  263.       $last_value = $obj->{'value'};
  264.       $obj->{'name'} = '__UNMONITOR__'
  265.     }
  266.     untie $$rvar;
  267.     $$rvar = $last_value;
  268.   }
  269.  
  270.  
  271. 局所変数 $obj をブロック {} 内で定義します。こうすることで $obj の有効範
  272.  
  273. 囲をブロック内に限定することができます。ブロックから抜けた時点で $obj は
  274.  
  275. 無効となり、オブジェクトのリファレンスカウントが -1 されるため、untie で
  276.  
  277. オブジェクトを廃棄することができます。
  278.  
  279.   また、untie される時にメソッド DESTORY が呼び出されますが、変数の監視
  280.  
  281. を止めたわけですから、DESTROY のメッセージを出力しない方が良いでしょう。
  282.  
  283. そこで、オブジェクトの name に __UNMONITOR__ をセットし、DESTROY でチェッ
  284.  
  285. クすることにします。
  286.  
  287.  
  288.   # 修正版  
  289.   sub DESTROY {
  290.     my $obj = shift;
  291.     if( $obj->{'name'} ne '__UNMONITOR__' ){
  292.       print 'DESTORY $', "$obj->{'name'}\n";
  293.     }
  294.   }
  295.  
  296.  
  297. プログラムの修正は簡単ですね。オブジェクトから name の値を取り出し、それ
  298.  
  299. を __UNMONITOR__ と比較するだけです。違っていれば、メッセージを出力しま
  300.  
  301. す。
  302.  
  303.   それでは、untie を unmonitor に変更して、実行してみましょう。
  304.  
  305.  
  306.   $x = 10;
  307.   tie $x, 'MonScalar', 'x', $x;
  308.   $y = $x;
  309.   print "y = $y\n";
  310.   $x = 100;
  311.   $z = $x;
  312.   print "z = $z\n";
  313.   MonScalar->unmonitor( \$x );
  314.   print "x = $x\n";
  315.  
  316.  
  317.   実行結果
  318.  
  319.   Read : $x -> 10
  320.   y = 10
  321.   Write : $x <- 100
  322.   Read : $x -> 100
  323.   z = 100
  324.   x = 100
  325.  
  326.  
  327. 監視を止めた後でも $x の値が 100 となります。正常に動作していますね。
  328.  
  329.  
  330. ○配列とタイ
  331.  
  332.   次は配列です。配列にタイを適用する場合、個々の要素へのアクセスの他にも、
  333.  
  334. push, pop など関数を使ったアクセスがあります。ところが、現在のところ配列
  335.  
  336. のタイでサポートされている操作は、要素の読み書きのみです。まあ、近い将来
  337.  
  338. に改善されると思います。
  339.   
  340.   配列の場合、tie が実行されると TIEARRAY が呼び出されます。そして、各要
  341.  
  342. 素にアクセスするたびに、次のメソッドが呼び出されます。
  343.  
  344.  
  345.        アクション  | 呼び出されるメソッド
  346.        ------------+------------------------------------
  347.        読み出し    | $obj->FETCH( $index );
  348.        書き込み    | $obj->STORE( $index, $new_value );
  349.        廃棄        | $obj->DESTROY();
  350.  
  351.  
  352. メソッドの名前はスカラーと同じですが、アクセスした要素の添字が渡されるこ
  353.  
  354. とに注意してください。
  355.  
  356.   それでは簡単な実行例として、配列のアクセスを監視するプログラムを作って
  357.  
  358. みましょう。最初にパッケージ MonArray を定義します。
  359.  
  360.  
  361.   package MonArray;
  362.  
  363.   sub TIEARRAY {
  364.     my ($pkg, $name, $ra) = @_;
  365.     my $obj = {
  366.       name => $name, array => [@$ra],
  367.     };
  368.     bless $obj, $pkg;
  369.     $obj;
  370.   }
  371.  
  372.   sub FETCH {
  373.     my ($obj, $index) = @_;
  374.     my $value = $obj->{'array'}->[$index];
  375.     print 'Read : $',$obj->{'name'}, "[$index] -> $value\n";
  376.     $value;
  377.   }
  378.  
  379.   sub STORE {
  380.     my ($obj, $index, $new_value) = @_;
  381.     print 'Write : $',$obj->{'name'}, "[$index] <- $new_value\n";
  382.     $obj->{'array'}->[$index] = $new_value;
  383.   }
  384.  
  385.   sub DESTROY {
  386.     my $obj = shift;
  387.     if( $obj->{'name'} ne '__UNMONITOR__' ){
  388.       print 'DESTORY @', "$obj->{'name'}\n";
  389.     }
  390.   }
  391.  
  392.   sub unmonitor {
  393.     my ($pkg, $rvar) = @_;
  394.     my $last_array;
  395.     {
  396.       my $obj = tied @$rvar;
  397.       $last_array = $obj->{'array'};
  398.       $obj->{'name'} = '__UNMONITOR__'
  399.     }
  400.     untie @$rvar;
  401.     @$rvar = @$last_array;
  402.   }
  403.  
  404.  
  405.   スカラーと同様に、TIEARRAY には配列名と配列そのものを渡します。配列を
  406.  
  407. 渡す時はリファレンスを使った方が簡単です。次にオブジェクトを生成し、名前
  408.  
  409. を name に、配列は無名の配列にコピーして array にセットします。後はオブ
  410.  
  411. ジェクトをブレスして返すだけです。FETCH と STORE は簡単です。引数として
  412.  
  413. 渡された添字で、オブジェクトに格納された無名の配列にアクセスすればいいわ
  414.  
  415. けです。監視を止める場合は、スカラーと同様に unmonitor を使います。オブ
  416.  
  417. ジェクトに格納されている配列を、監視していた配列に代入するだけです。
  418.  
  419.   それでは実行してみましょう。
  420.  
  421.   package main;
  422.  
  423.   @a = (10, 20, 30);
  424.   tie @a, 'MonArray', 'a', \@a;
  425.   $x = $a[1];
  426.   print "x = $x\n";
  427.   $a[1] = 200;
  428.   $y = $a[1];
  429.   print "y = $y\n";
  430.   MonArray->unmonitor( \@a );
  431.   print "@a\n";
  432.  
  433.  
  434.   実行結果
  435.  
  436.   Read : $a[1] -> 20
  437.   x = 20
  438.   Write : $a[1] <- 200
  439.   Read : $a[1] -> 200
  440.   y = 200
  441.   10 200 30
  442.  
  443.  
  444.   最初に tie を使って配列 @a とクラス MonArray を結び付けます。この後 @a 
  445.  
  446. の要素にアクセスすると、MonArray のメソッド FETCH と STORE が呼び出され
  447.  
  448. ます。unmonitor で監視を止めた後でも、配列の値はきちんと更新されています
  449.  
  450. ね。
  451.  
  452.  
  453. ○ハッシュとタイ
  454.  
  455.   配列の場合と異なり、タイによるハッシュへのアクセスは、個々の要素へのア
  456.  
  457. クセス、ハッシュ全体の操作、関数による操作の全てを完全にサポートしていま
  458.  
  459. す。
  460.  
  461.   ハッシュの場合、tie が実行されると TIEHASH が呼び出されます。そして、
  462.  
  463. ハッシュにアクセスするたびに、次のメソッドが呼び出されます。
  464.  
  465.  
  466.         操作例             | 呼び出されるメソッド
  467.         -------------------+----------------------
  468.         $h{a};             | $obj->FETCH('a');
  469.         $h{a} = 1;         | $obj->STORE('a', 1);
  470.         delete $h{a};      | $obj->DELETE('a');
  471.         exists $h{a};      | $obj->EXISTS('a');
  472.         %h = ();           | $obj->CLEAR();
  473.                            |
  474.         %h = ( a => 1 );   | $obj->CLEAR();
  475.                            | $obj->STORE('a');
  476.                            |
  477.         keys, values, each | $lk = $obj->FIRSTKEY();
  478.                            | do {
  479.                            |   $val = $obj->FETCH($lk);
  480.                            | } while ( $lk = $obj->NEXTKEY($lk) );
  481.  
  482.  
  483.   FIRSTKEY は最初のキーを、NEXTKEY は次のキーを返すように作る必要があり
  484.  
  485. ます。keys ではこの2つのメソッドが呼び出され、values や each では、各々
  486.  
  487. のキーについて FETCH が呼び出されます。
  488.  
  489.   定義するメソッドが多くで面倒だと感じる方は、Tie::Hash, Tie::StdHash と
  490.  
  491. いう、タイハッシュに対する基本クラスを定義したモジュールが標準ライブラリ
  492.  
  493. に用意されているので、これを継承するといいでしょう。
  494.  
  495.  
  496.   それでは簡単な実行例として、ハッシュのアクセスを監視するプログラムを作っ
  497.  
  498. てみましょう。簡単な例題ということで、要素へのアクセスとハッシュ全体をク
  499.  
  500. リアする操作だけを監視することにします。最初にパッケージ MonHash を定義
  501.  
  502. します。
  503.  
  504.  
  505.   package MonHash;
  506.  
  507.   sub TIEHASH {
  508.     my ($pkg, $name, $rh) = @_;
  509.     my $obj = {
  510.       name => $name, hash => {%$rh},
  511.     };
  512.     bless $obj, $pkg;
  513.     $obj;
  514.   }
  515.  
  516.   sub FETCH {
  517.     my ($obj, $index) = @_;
  518.     my $value = $obj->{'hash'}->{$index};
  519.     print 'Read : $', $obj->{'name'}, "{$index} -> $value\n";
  520.     $value;
  521.   }
  522.  
  523.   sub STORE {
  524.     my ($obj, $index, $new_value) = @_;
  525.     print 'Write : $', $obj->{'name'}, "{$index} <- $new_value\n";
  526.     $obj->{'hash'}->{$index} = $new_value;
  527.   }
  528.  
  529.   sub CLEAR {
  530.     my $obj = shift;
  531.     print 'Clear : %', "$obj->{'name'}\n";
  532.     $obj->{'hash'} = {};
  533.   }
  534.  
  535.   sub DESTROY {
  536.     my $obj = shift;
  537.     if( $obj->{'name'} ne '__UNMONITOR__' ){
  538.       print 'DESTORY %', "$obj->{'name'}\n";
  539.     }
  540.   }
  541.  
  542.   sub unmonitor {
  543.     my ($pkg, $rvar) = @_;
  544.     my $last_hash;
  545.     {
  546.       my $obj = tied %$rvar;
  547.       $last_hash = $obj->{'hash'};
  548.       $obj->{'name'} = '__UNMONITOR__'
  549.     }
  550.     untie %$rvar;
  551.     %$rvar = %$last_hash;
  552.   }
  553.  
  554.  
  555.   スカラーや配列と同様に、TIEHASH にはハッシュ名とハッシュそのものを渡し
  556.  
  557. ます。ハッシュを渡す時はリファレンスを使います。次にオブジェクトを生成し、
  558.  
  559. 名前を name に、ハッシュの値は無名のハッシュにコピーして hash にセットし
  560.  
  561. ます。後はオブジェクトをブレスして返すだけです。FETCH と STORE は簡単で
  562.  
  563. す。引数として渡された添字で、オブジェクトに格納された無名のハッシュにア
  564.  
  565. クセスすればいいわけです。CLEAR はもっと簡単ですね。メッセージを出力した
  566.  
  567. ら、ハッシュを空にするだけです。unmonitor も配列をハッシュに変えただけで
  568.  
  569. す。
  570.  
  571.   それでは実行してみましょう。
  572.  
  573.   package main;
  574.  
  575.   %h = (a => 10, b => 20, c => 30);
  576.   print %h, "\n";
  577.   tie %h, 'MonHash', 'h', \%h;
  578.   $x = $h{'b'};
  579.   print "x = $x\n";
  580.   $h{'b'} = 200;
  581.   $y = $h{'b'};
  582.   print "y = $y\n";
  583.   %h = ( a => 100, b => 200, c => 300 );
  584.   MonHash->unmonitor( \%h );
  585.   print %h;
  586.  
  587.  
  588.   実行結果
  589.  
  590.   a10b20c30
  591.   Read : $h{b} -> 20
  592.   x = 20
  593.   Write : $h{b} <- 200
  594.   Read : $h{b} -> 200
  595.   y = 200
  596.   Clear : %h
  597.   Write : $h{a} <- 100
  598.   Write : $h{b} <- 200
  599.   Write : $h{c} <- 300
  600.   a100b200c300
  601.  
  602.  
  603.   もう説明しなくてもいいですね。正常に動作しています。
  604.  
  605.  
  606. ○パッケージ Monitor の作成 
  607.  
  608.   ここまで、スカラー、配列、ハッシュの監視プログラムを作りましたが、いち
  609.  
  610. いちクラスを指定して tie 関数を呼び出すのは面倒ですね。そこで、与えられ
  611.  
  612. た変数の種類を調べて、適切な tie 関数を呼び出すプログラムを作りましょう。
  613.  
  614. 作成するプログラムは、変数を監視する monitor と監視を止める unmonitor の
  615.  
  616. 2つです。monitor は変数のリファレンスと名前を、unmonitor は変数のリファ
  617.  
  618. レンスを引数として受け取ります。
  619.  
  620.  
  621.   # 使用例
  622.   $x = 100;
  623.   monitor( \$x, 'x' );
  624.   unmonitor( \$x );
  625.   
  626.  
  627. monitor と unmonitor はパッケージ Monitor に定義します。プログラムは次
  628.  
  629. のようになります。
  630.  
  631.  
  632.   # パッケージの定義(Monitor.pm)
  633.   package Monitor;
  634.   use Exporter;
  635.   @ISA = (Exporter);
  636.   @EXPORT_OK = ('monitor', 'unmonitor');
  637.  
  638.   # 変数を監視する
  639.   sub monitor {
  640.     my ($rvar, $name) = @_;
  641.     my $type = ref( $rvar );     # 型のチェック
  642.     if( $type eq 'SCALAR' ){
  643.       tie $$rvar, 'MonScalar', $name, $$rvar;
  644.     } elsif( $type eq 'ARRAY' ){
  645.       tie @$rvar, 'MonArray', $name, $rvar;
  646.     } elsif( $type eq 'HASH' ){
  647.       tie %$rvar = 'MonHash', $name, $rvar;
  648.     } else {
  649.       print STDERR "リファレンスが必要です\n";
  650.     }
  651.   }
  652.  
  653.   # 変数の監視を止める
  654.   sub unmonitor {
  655.     my $rvar = shift;
  656.     my $type = ref( $rvar );     # 型のチェック
  657.     if( $type eq 'SCALAR' ){
  658.       MonScalar->unmonitor( $rvar );
  659.     } elsif( $type eq 'ARRAY' ){
  660.       MonArray->unmonitor( $rvar );
  661.     } elsif( $type eq 'HASH' ){
  662.       MonHash->unmonitor( $rvar );
  663.     } else {
  664.       print STDERR "リファレンスが必要です\n";
  665.     }
  666.   }
  667.  
  668.  
  669. 2つのプログラムともに、関数 ref を呼び出してリファレンス先のデータの種
  670.  
  671. 類を調べ、適切な関数を呼び出すだけです。MonScalar, MonArray, MonHash は
  672.  
  673. ファイル Monitor.pm にまとめて定義しておきます。
  674.  
  675.  
  676.   それでは実行例を示します。
  677.  
  678.  
  679.   # テストプログラム(montest.pl)
  680.   use Monitor ('monitor', 'unmonitor');
  681.  
  682.   $x = 10;
  683.   @a = (100, 200, 300);
  684.   %h = (a => 1, b => 2, c => 3 );
  685.  
  686.   monitor( \$x, 'x' );
  687.   monitor( \@a, 'a' );
  688.   monitor( \%h, 'h' );
  689.  
  690.   $x = 20;
  691.   $y1 = $x;
  692.   print "y1 = $y1\n";
  693.  
  694.   $a[2] = 3000;
  695.   $y2 = $a[2];
  696.   print "y2 = $y2\n";
  697.  
  698.   $h{'c'} = 30;
  699.   $y3 = $h{'c'};
  700.   print "y3 = $y3\n";
  701.  
  702.   unmonitor( \$x );
  703.   unmonitor( \@a );
  704.   unmonitor( \%h );
  705.  
  706.   print "x = $x\n";
  707.   print "a = @a\n";
  708.   print "h = ", %h, "\n";
  709.  
  710.  
  711.   実行結果
  712.  
  713.   Write : $x <- 20
  714.   Read : $x -> 20
  715.   y1 = 20
  716.   Write : $a[2] <- 3000
  717.   Read : $a[2] -> 3000
  718.   y2 = 3000
  719.   Write : $h{c} <- 30
  720.   Read : $h{c} -> 30
  721.   y3 = 30
  722.   x = 20
  723.   a = 100 200 3000
  724.   h = a1b2c30
  725.  
  726.  
  727.   正常に動作していますね。
  728.  
  729.  
  730.   タイの最も有効な利用方法は、ハッシュとデータベースを結び付けることです
  731.  
  732. が、本講座の範囲を超えるので説明を割愛いたします。また、ファイルハンドル
  733.  
  734. とタイの説明も割愛させていただきます。興味のある方は参考文献を読んでくだ
  735.  
  736. さい。
  737.  
  738.  
  739. ○おわりに
  740.  
  741.   最近、インタプリタ形式のプログラミング言語(スクリプト言語ともいう)が
  742.  
  743. 注目を集めています。その中で、Perl は CGI スクリプトを書くためのプログラ
  744.  
  745. ミング言語として、その普及度は目を見張るものがあります。この講座では、筆
  746.  
  747. 者のスキル不足のため、CGI プログラミングを取り上げることはできませんでし
  748.  
  749. た。しかしながら、Perl の基本からオブジェクト指向まで、プログラミング言
  750.  
  751. 語としての機能は一通り説明できたと思っています。
  752.  
  753.   Perl は応用範囲の広いプログラミング言語です。CGI やネットワークの他に
  754.  
  755. も、GUI ツールキット Tk を利用するためのモジュール Tk.pm [*2] をロードす
  756.  
  757. ることで、Perl でも GUI アプリケーションを作成することができます。これか
  758.  
  759. らも、いろいろな分野で Perl が利用されることでしょう。皆さんも Perl を使っ
  760.  
  761. てプログラミングを楽しんでください。
  762.  
  763.   最後になりましたが、この講座が少しでも皆様のお役に立てれば、筆者として
  764.  
  765. はこれほどの幸せはありません。長い間お付き合いいただいた読者の皆様、なら
  766.  
  767. びに編集スタッフの方々に感謝の意を表します。
  768.  
  769.  
  770.     [*2]    Perl と Tk.pm の組み合わせを「Perl/Tk」といいます。なお、
  771.           Perl/Tk を実行するために Tcl/Tk は必要ありません。use Tk; で 
  772.           Tk の利用が可能になります。
  773.             Perl のモジュールは総合 Perl アーカイブネットワーク (CPAN) 
  774.           からダウンロードすることができます。ActivePerl 用 Tk.pm の入手
  775.           先は、須栗歩人氏のホームページ 
  776.  
  777.                   http://members.xoom.com/tcltk/index.html 
  778.  
  779.           を参照してください。Tcl/Tk や Perl/Tk の情報がとても参考になり
  780.           ます。
  781.  
  782.  
  783.                               ―参考文献―
  784.  
  785.  [1] Larry Wall, Tom Christiansen, Randal L. Schwartz 共著「プログラミン
  786.      グPerl」改訂版 オライリー・ジャパン 1997
  787.  
  788.  [2] Sriram Srinivasan  著「実用Perlプログラミング」オライリー・ジャ
  789.      パン 1998
  790.  
  791. (EOF)
  792.  
  793.